#ifndef VSQTGUI_H
#define VSQTGUI_H

#include "vsLogic.h"
#include <QWidget>
#include <QSystemTrayIcon>

class QTabWidget;
class QTextEdit;
class QTextBrowser;
class QListView;
class QListWidget;
class QAction;
class QMenu;
class QSpinBox;
class QLineEdit;
class QModelIndex;
class QHeaderView;
class QPushButton;
class QVBoxLayout;

class vsMLModel;
class vsMLDelegate;


// drag'n'drop-enabled widget to accept file drops from os
class dWgt : public QWidget
{
    Q_OBJECT
public:
    dWgt(QWidget *parent = 0);
    ~dWgt() {}

    void dragEnterEvent(QDragEnterEvent *event) override;
    void dragMoveEvent (QDragMoveEvent  *event) override;
    void dropEvent     (QDropEvent      *event) override;

signals:
    void fileDropped(const QString &uri);
};



class vsWindow : public QWidget
{
    Q_OBJECT
    friend class vsQtGui;

public:
    explicit vsWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0);
    ~vsWindow();

    void addWatchedFolder(const QString &path);     // adds widgets
    void removeWatchedFolder(const QString &path);

public slots:
    void onLogMessage(QString msg, vsLog::msgType type);
    void iconActivated(QSystemTrayIcon::ActivationReason reason);
    void onExit();

signals:
    void closeRequest(); /// user tries to close the window

    void watchFolder(QString path);
    void stopWatchingFolder(QString path);

protected:
    dWgt         *filesPage   = 0;
    QListView    *mediaList   = 0;
    QHeaderView  *mlHeader    = 0;
    QTextBrowser *logWidget   = 0;
    QTabWidget   *tabs        = 0;
    vsMLDelegate *mlDrawer    = 0;

    bool trayAvailable        = false;
    bool hideToTray           = false;
    bool logNotify            = true;
    bool copyHTML             = false;

    void changeEvent(QEvent      *) override;
    void closeEvent (QCloseEvent *) override;

    QAction         *restoreAction  = 0;
    QAction         *quitAction     = 0;
    QSystemTrayIcon *trayIcon       = 0;
    QMenu           *trayIconMenu   = 0;
    QSpinBox        *portSpin       = 0;
    QLineEdit       *url            = 0;
    QPushButton     *searchBtn      = 0;
    QLineEdit       *search         = 0;
    QVBoxLayout     *watchedFList   = 0;
    QLineEdit       *ipCheckService = 0;
    QSpinBox        *fsIntervalSpin = 0;

    QMap<QString, QWidget*> watchedFolders;

    QString lastDir;
    QString ipCheckServiceStr;
    int unreadLogMsgs = 0;
};



class vsQtGui : public vsUI
{
    Q_OBJECT

public:
    explicit vsQtGui(QObject *parent = 0);
    ~vsQtGui();

    void onConnected() override;
    QStringList getIdOrder() const override;

private slots:
    void onFileAdded(vsMediaFile *);
    void onFileRemoved(QString id);                                  // received from logic
    void onMediaIDChanged(QString oldID, vsMediaFile * updatedData); // received from logic

    void onFileInfoUpdated();
    void onNetworkInfoUpdated(QString id, int requests, int uprate, int dlrate, qint64 seeded);

    void onSearchToggled   (bool on);
    void onHeaderColToggled(bool on);
    void onMLHeaderMenu(const QPoint &pos);
    void onMLMenu(const QPoint &pos);
    void onMLMenuAddFiles();

    void onPortSet(int newPort);
    void onFWScanIntervalSet(int newInterval);
    void onExit();

    void onCopySelectedURLs();
    void onShowSelectedFiles();
    void onDeleteSelectedMedias();

    void watchFolder(const QString &path);  // received from logic, must show it in UI
    void stopWatchingFolder(const QString &path);

protected:
    vsMLModel *files    = 0;
    vsWindow  *win      = 0;
    QMenu     *mlMenu   = 0;

    QAction *copyURLAction = 0;
    QAction *showFilesAction = 0;
    QAction *removeMediasAction = 0;
    QAction *addMediasAction = 0;

    QMenu *mlHeaderMenu = 0;
    QMap<int, bool> headerCols; // visible media list header sections
    QVector<bool> headerSortOrders; // section number as index, true if ascending

    void setupMLHeader(const QStringList &ids, const QList<int> &widths);

    bool eventFilter(QObject *obj, QEvent *event) override;

    inline Qt::SortOrder sortOrderForHeaderSection(int section)
    {
        if (headerSortOrders.size() <= section)
            headerSortOrders.resize(section + 1);

        const bool &asc = headerSortOrders[section];
        Qt::SortOrder result = asc ? Qt::AscendingOrder : Qt::DescendingOrder;
        headerSortOrders[section] = !asc;

        return result;
    }

private:
    QStringList popupIDs;

};


#endif // VSQTGUI_H
